/*************************************************************
   Copyright(C) 2017 by MartyrCompany
   All rights reserved.
   
   CtrlItemDataDefaultFormatHelper.cs
   UnityFramework
   
   Created by WuIslet on 2022-05-31.
   
*************************************************************/

#define USE_EDITOR_UI_CONTROLDATA
using System.Text;

public class CtrlItemDataDefaultFormatHelper
{
    public static string ToUpperFirst(string str)
    {
        if (string.IsNullOrEmpty(str))
            return null;

        var firstChar = char.ToUpper(str[0]);
        var ret = firstChar + str.Substring(1);
        return ret;
    }
    public static string ToLowerFirst(string str)
    {
        if (string.IsNullOrEmpty(str))
            return null;

        var firstChar = char.ToLower(str[0]);
        var ret = firstChar + str.Substring(1);
        return ret;
    }

    protected CtrlItemData data;
    public void SetData(CtrlItemData d)
    {
        data = d;
    }

    private string DecodeArgString(string arg, bool onlyFinalArg = false)
    {
        arg = arg.Trim('/');
        if (string.IsNullOrEmpty(arg))
        {
            if (arg == "/")
            {
                if (onlyFinalArg)
                    return "vm";
                else
                    return "nil";
            }
        }

        var list = arg.Split('/');
        if (onlyFinalArg)
        {
            var argName = list[list.Length - 1];
            if (string.IsNullOrEmpty(argName) || argName == "..")
                argName = "vm";
            return string.Format("{0}", argName);
        }
        else if (list.Length == 1)
        {
            return string.Format("\"{0}\"", list[0]);
        }
        else
        {
            var str = "";
            for (int i = 0; i < list.Length; i++)
            {
                str += string.Format("\"{0}\", ", list[i]);
            }
            return string.Format("{{{0}}}", str);
        }    
    }

    #region C#
    public string GetCSharpDefineCode(string accessLevel) //声明变量 //View
    {
        if (!data.IsHasTarget())
            return "";

        var propName = GetPropName();
        return string.Format("    {0} {1} {2};\r\n", accessLevel, data.type, propName);
    }

    public string GetCSharpInitCode() //初始化生成对象 //View
    {
        if (!data.IsHasTarget())
            return "";

        var propName = GetPropName();

#if USE_EDITOR_UI_CONTROLDATA
        switch (data.type)
        {
            case EUIControlDataType.GameObject:
                return string.Format("        {0} = transform.Find(\"{2}\").gameObject;\r\n", propName, data.type, data.targetsPath);
            case EUIControlDataType.HMI_Text:
            case EUIControlDataType.HMI_Button:
            case EUIControlDataType.HMI_Title:
            case EUIControlDataType.HMI_SlideButton:
            case EUIControlDataType.HMI_Toggle:
            case EUIControlDataType.HMI_Slider:
            case EUIControlDataType.HMI_TabGroupBtn:
            case EUIControlDataType.HMI_ScrollView:
            case EUIControlDataType.HMI_HorizontalItem:
                return string.Format("        {0} = transform.Find(\"{2}\").GetComponent<{1}>();\r\n        {0}.InitComponent(this);\r\n", propName, data.type, data.targetsPath);
            default:
                return string.Format("        {0} = transform.Find(\"{2}\").GetComponent<{1}>();\r\n", propName, data.type, data.targetsPath);
        }
#else
        return string.Format("        {0} = mUIData.GotIt(\"{0}\") as {1};\r\n", propName, data.type);
#endif
    }

    public string GetCSharpAddClickCode() //初始化注册 //View
    {
        if (!data.IsHasTarget())
            return "";

        var sb = new StringBuilder();
        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        switch (data.type)
        {
            case EUIControlDataType.HMI_Button:
            case EUIControlDataType.HMI_Title:
            case EUIControlDataType.Button:
            case EUIControlDataType.LPButton:
                sb.AppendFormat("        {0}.onClick.AddListener(() => OnButtonClick(\"{0}\"));\r\n", propName, upName);
                break;
            case EUIControlDataType.HMI_Toggle:
                sb.AppendFormat("        {0}.onValueChanged.AddListener((value) => OnButtonClick(\"{0}\", value ? 1 : 0));\r\n", propName, upName);
                break;
            case EUIControlDataType.HMI_SlideButton:
                sb.AppendFormat("        {0}.SetOnClick(OnButtonClick);\r\n", propName, upName);
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                sb.AppendFormat("        {0}.onValueChanged.AddListener(On{1}ValueChanged);\r\n", propName, upName);
                break;
            case EUIControlDataType.Slider:
                sb.AppendFormat("        {0}.onValueChanged.AddListener(On{1}ValueChanged);\r\n", propName, upName);
                break;
            default:
                break;
        }
        return sb.ToString();
    }

    public string GetCSharpBindTextCode() //绑定参数 //View
    {
        if (!data.IsHasTarget())
            return "";

        var propName = GetPropName();
        var sb = new StringBuilder();
        switch (data.type)
        {
            case EUIControlDataType.Text:
            case EUIControlDataType.TextMeshProUGUI:
                sb.AppendFormat("        Binder.Add(\"{0}\", (arg) => {{ {0}.text = (string)arg; }});\r\n", propName);
                break;
            case EUIControlDataType.Image:
            case EUIControlDataType.RawImage:
                sb.AppendFormat("        Binder.Add(\"{0}\", (arg) => {{ {0}.text = (string)arg; }});\r\n", propName); //todo bug
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                sb.AppendFormat("        Binder.Add(\"{0}\", (arg) => {{ {0}.text = (string)arg; }});\r\n", propName);
                break;
            case EUIControlDataType.Slider:
                sb.AppendFormat("        Binder.Add(\"{0}\", (arg) => {{ {0}.value = (float)arg; }});\r\n", propName);
                break;
            default:
                break;
        }

        for (int i = 0; i < CtrlItemData.BindAllTypes.Count; ++i)
        {
            var type = CtrlItemData.BindAllTypes[i];
            if (data.GetBindFlag(type))
            {
                var typeName = type.ToString();
                sb.AppendFormat("        Binder.Add(\"{0}{1}\", (arg) => {{ {0}{2} }});\r\n", propName, typeName,
                    CtrlItemData.GetCSharpBindCode(type));
            }
        }

        return sb.ToString();
    }

    public string GetCSharpClickFuncCode() //绑定点击事件 //View
    {
        if (!data.IsHasTarget())
            return "";

        var sb = new StringBuilder();
        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        switch (data.type)
        {
            case EUIControlDataType.Button:
                sb.AppendFormat("    private void On{1}Click()\r\n    {{\r\n        DoCommand(\"{0}\", 0);\r\n    }}\r\n", propName, upName);
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                sb.AppendFormat("    private void On{1}ValueChanged(string arg)\r\n    {{\r\n        DoCommand(\"{0}\", arg);\r\n    }}\r\n", propName, upName);
                break;
            case EUIControlDataType.Slider:
                sb.AppendFormat("    private void On{1}ValueChanged(float arg)\r\n    {{\r\n        DoCommand(\"{0}\", arg);\r\n    }}\r\n", propName, upName);
                break;
            default:
                break;
        }
        return sb.ToString();
    }

    public string GetCSharpViewModleDefineCode(string accessLevel) //声明变量 //ViewModel
    {
        if (!data.IsHasTarget())
            return "";

        var propName = GetPropName();
        return string.Format("    {0} {1} {2};\r\n", accessLevel, "BindProper", propName);
    }

    //public string GetCSharpViewModuleChildClickRegister() //右键复制生成的生成对象 //ViewModel
    //{
    //    if (!data.IsHasTarget())
    //        return "";

    //    var sb = new StringBuilder();
    //    var propName = GetPropName();
    //    var upName = ToUpperFirst(propName);
    //    switch (data.type)
    //    {
    //        case EUIControlDataType.Button:
    //            sb.AppendFormat("        view.{0}.onClick.AddListener(On{1}Click);\r\n", propName, upName);
    //            break;
    //        case EUIControlDataType.InputField:
    //        case EUIControlDataType.TMP_InputField:
    //            sb.AppendFormat("        view.{0}.onValueChanged.AddListener(On{1}ValueChanged);\r\n", propName, upName);
    //            break;
    //        case EUIControlDataType.Slider:
    //            sb.AppendFormat("        view.{0}.onValueChanged.AddListener(On{1}ValueChanged);\r\n", propName, upName);
    //            break;
    //        default:
    //            break;
    //    }
    //    return sb.ToString();
    //}

    //public string GetCSharpViewModuleChildClickFunction() //右键复制生成的注册函数 //ViewModel
    //{
    //    if (!data.IsHasTarget())
    //        return "";

    //    var sb = new StringBuilder();
    //    var propName = GetPropName();
    //    var upName = ToUpperFirst(propName);
    //    switch (data.type)
    //    {
    //        case EUIControlDataType.Button:
    //            sb.AppendFormat("    private void On{0}Click()\r\n    {{\r\n    }}\r\n", upName);
    //            break;
    //        case EUIControlDataType.InputField:
    //        case EUIControlDataType.TMP_InputField:
    //            sb.AppendFormat("    private void On{0}ValueChanged(string arg)\r\n    {{\r\n    }}\r\n", upName);
    //            break;
    //        case EUIControlDataType.Slider:
    //            sb.AppendFormat("    private void On{0}ValueChanged(string arg)\r\n    {{\r\n    }}\r\n", upName);
    //            break;
    //        default:
    //            break;
    //    }
    //    return sb.ToString();
    //}

    public string GetCSharpViewModelRegister() //右键复制 给window文件的注册 //ViewModel
    {
        if (!data.IsHasTarget())
            return "";

        var sb = new StringBuilder();
        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        sb.AppendFormat("    {0} = new BindProper(this, \"{0}\");\r\n", propName);
        switch (data.type)
        {
            case EUIControlDataType.Button:
                sb.AppendFormat("    {0}.SetCallback(On{1}Click);\r\n", propName, upName);
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                sb.AppendFormat("    {0}.SetCallback(On{1}ValueChanged);\r\n", propName, upName);
                break;
            case EUIControlDataType.Slider:
                sb.AppendFormat("    {0}.SetCallback(On{1}ValueChanged);\r\n", propName, upName);
                break;
            default:
                break;
        }
        return sb.ToString();
    }

    public string GetCSharpViewModelFunc() //右键复制 给window文件的注册 //ViewModel
    {
        if (!data.IsHasTarget())
            return "";

        var sb = new StringBuilder();
        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        switch (data.type)
        {
            case EUIControlDataType.Button:
                sb.AppendFormat("    public void On{0}Click()\r\n    {{\r\n    }}\r\n", upName);
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                sb.AppendFormat("    public void On{0}ValueChanged(int iarg, string sarg)\r\n    {{\r\n    }}\r\n", upName);
                break;
            case EUIControlDataType.Slider:
                sb.AppendFormat("    public void On{0}ValueChanged(float arg)\r\n    {{\r\n    }}\r\n", upName);
                break;
            default:
                break;
        }
        return sb.ToString();
    }
    #endregion C#

    #region lua
    public string GetLuaDefineCode(string accessLevel)
    {
        return "";
    }

    public string GetLuaInitCode() //初始化生成对象
    {
        if (!data.IsHasTarget())
            return "";

        var sb = new StringBuilder();
        var type = data.type;
        if (UIControlDataType.LuaNameChange.ContainsKey(type))
        {
            type = UIControlDataType.LuaNameChange[type];
        }

        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        var bindTarget = string.Format("\"{0}\"", propName);
        var extraFunc = "";
        if (!string.IsNullOrEmpty(data.extraFunc[CtrlItemData.BINDNULLINDEX]))
        {
            bindTarget = DecodeArgString(data.extraFunc[CtrlItemData.BINDNULLINDEX]);

            if (!data.extraGeneratorFunc[CtrlItemData.BINDNULLINDEX])
                extraFunc = string.Format(", nil, self.{0}DefaultViewFunction", propName);
            else
                extraFunc = "";
        }

        int arg;
        var format = "";
        switch (data.type)
        {
            case EUIControlDataType.Button:
                format = "\r\n    self.{0} = UIControls.{1}(self, \"{2}\")\r\n";
                if (!data.isNotGeneratorCode)
                    format += "    self:reg(self.{0}, \"on{3}Click\"{6})\r\n";
                break;
            case EUIControlDataType.RedDot:
                format = "\r\n    self.{0} = UIControls.{1}(self, \"{2}\")\r\n";
                if (!data.isNotGeneratorCode)
                {
                    if (!string.IsNullOrEmpty(data.arg))
                    {

                    }
                    else
                        format += "    self:reg(self.{0}, {5}{6})\r\n";
                }
                break;
            case EUIControlDataType.OSALScrollView:
            case EUIControlDataType.OSALGridView:
                if (string.IsNullOrEmpty(data.arg))
                {
                    format = "\r\n    self.{0} = UIControls.{1}(self, \"{2}\", nil)\r\n";
                }
                else if (data.arg.Contains(".") || (int.TryParse(data.arg, out arg)))
                {
                    format = "\r\n    self.{0} = UIControls.{1}(self, \"{2}\", {4})\r\n";
                }
                else
                {
                    format = "\r\n    self.{0} = UIControls.{1}(self, \"{2}\", \"{4}\")\r\n";
                }
                if (!data.isNotGeneratorCode)
                    format += "    self:reg(self.{0}, {5}{6})\r\n";
                break;
            case EUIControlDataType.OSALScrollViewLazy:
                if (string.IsNullOrEmpty(data.arg))
                {
                    format = "\r\n    self.{0} = UIControls.OSALScrollView(self, \"{2}\", nil)\r\n";
                }
                else if (data.arg.Contains(".") || (int.TryParse(data.arg, out arg)))
                {
                    format = "\r\n    self.{0} = UIControls.OSALScrollView(self, \"{2}\", {4})\r\n";
                }
                else
                {
                    format = "\r\n    self.{0} = UIControls.OSALScrollView(self, \"{2}\", \"{4}\")\r\n";
                }
                if (!data.isNotGeneratorCode)
                    format += "    self:reg(self.{0}, {5}{6})\r\n";
                break;
            case EUIControlDataType.OSALGridViewLazy:
                if (data.arg.Contains(".") || (int.TryParse(data.arg, out arg)))
                {
                    format = "\r\n    self.{0} = UIControls.OSALGridView(self, \"{2}\", {4})\r\n";
                }
                else
                {
                    format = "\r\n    self.{0} = UIControls.OSALGridView(self, \"{2}\", \"{4}\")\r\n";
                }
                if (!data.isNotGeneratorCode)
                    format += "    self:reg(self.{0}, {5}{6})\r\n";
                break;
            case EUIControlDataType.Child:
                if (data.arg.Contains(".") || (int.TryParse(data.arg, out arg)))
                {
                    format = "\r\n    self.{0} = UIControls.ChildContainer(self, \"{2}\", {4})\r\n";
                }
                else
                {
                    format = "\r\n    self.{0} = UIControls.ChildContainer(self, \"{2}\", \"{4}\")\r\n";
                }
                if (!data.isNotGeneratorCode)
                    format += "    self:reg(self.{0}, {5}{6})\r\n";
                break;
            case EUIControlDataType.PanelView:
                format = "\r\n    self.{0} = {4}(self, \"{2}\")\r\n";
                if (!data.isNotGeneratorCode)
                    format += "    self:reg(self.{0}, {5}{6})\r\n";
                break;
            default:
                format = "\r\n    self.{0} = UIControls.{1}(self, \"{2}\")\r\n";
                if (!data.isNotGeneratorCode)
                    format += "    self:reg(self.{0}, {5}{6})\r\n";
                break;
        }
        if (!string.IsNullOrEmpty(format))
            sb.AppendFormat(format, propName, type, data.targetsPath, upName, data.arg, bindTarget, extraFunc);

        for (int i = 0; i < CtrlItemData.BindAllTypes.Count; ++i)
        {
            var bindType = CtrlItemData.BindAllTypes[i];
            if (data.GetBindFlag(bindType))
            {
                var typeName = bindType.ToString();
                var bindConstName = typeName;
                if (UIControlDataType.BindNameChange.ContainsKey(bindConstName))
                {
                    bindConstName = UIControlDataType.BindNameChange[bindConstName];
                }

                bindTarget = string.Format("\"{0}{1}\"", propName, typeName);
                extraFunc = "";
                if (!string.IsNullOrEmpty(data.extraFunc[i]))
                {
                    bindTarget = DecodeArgString(data.extraFunc[i]);

                    if (!data.extraGeneratorFunc[i])
                        extraFunc = string.Format(", self.{0}{1}ViewFunction", propName, typeName);
                    else
                        extraFunc = "";
                }
                if (!data.isNotGeneratorCode)
                {
                    sb.AppendFormat(
                        "    self:reg(self.{0}, {3}, UIBind.{2}{4})\r\n",
                        propName, typeName, bindConstName, bindTarget, extraFunc);
                }
            }
        }

        return sb.ToString();
    }

    public string GetLuaExtraFuncCode(bool isOpen) //初始化函数
    {
        if (!data.IsHasTarget())
            return "";

        var sb = new StringBuilder();
        var propName = GetPropName();

        switch (data.type)
        {
            case EUIControlDataType.RedDot:
                if (!data.isNotGeneratorCode)
                {
                    if (!string.IsNullOrEmpty(data.arg))
                    {
                        if (isOpen)
                        {
                            sb.AppendFormat("    RedDotManager.registRedDot(UIConst.{1}, self.{0})\r\n", propName, data.arg);
                        }
                        else
                        {
                            sb.AppendFormat("    RedDotManager.unregistRedDot(UIConst.{1}, self.{0})\r\n", propName, data.arg);
                        }
                    }
                }
                break;
            default:
                break;
        }

        return sb.ToString();
    }

    public string GetLuaViewModuleChildRegister() //右键复制生成的生成对象
    {
        if (!data.IsHasTarget())
            return "";
        if (data.isNotGeneratorCode)
            return "";

        var sb = new StringBuilder();
        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        switch (data.type)
        {
            case EUIControlDataType.Button:
                sb.AppendFormat("    self.{0}:addEventClick(self.on{1}Click)\r\n", propName, upName);
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                sb.AppendFormat("    self.{0}:addEventValueChanged(self.on{1}ValueChanged)\r\n", propName, upName);
                break;
            case EUIControlDataType.Slider:
                sb.AppendFormat("    self.{0}:addEventValueChanged(self.on{1}ValueChanged)\r\n", propName, upName);
                break;
            default:
                break;
        }
        return sb.ToString();
    }

    public string GetLuaViewModuleChildFunc(string viewModelName) //右键复制生成的注册函数
    {
        if (!data.IsHasTarget())
            return "";

        var sb = new StringBuilder();
        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        switch (data.type)
        {
            case EUIControlDataType.Button:
                sb.AppendFormat("function {1}:on{0}Click(sender)\r\n    \r\nend\r\n", upName, viewModelName);
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                sb.AppendFormat("function {1}:on{0}ValueChanged(sender, str)\r\n    \r\nend\r\n", upName, viewModelName);
                break;
            case EUIControlDataType.Slider:
                sb.AppendFormat("function {1}:on{0}ValueChanged(sender, str)\r\n    \r\nend\r\n", upName, viewModelName);
                break;
            default:
                break;
        }
        return sb.ToString();
    }

    public string GetLuaViewModelRegister() //右键复制 给window文件的注册
    {
        if (!data.IsHasTarget())
            return "";

        var sb = new StringBuilder();
        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        switch (data.type)
        {
            case EUIControlDataType.Button:
                sb.AppendFormat("    self:registerCommand(\"on{0}Click\", Slot(self.on{0}Click, self))\r\n", upName);
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                sb.AppendFormat("    self:registerCommand(\"on{0}ValueChanged\", Slot(self.on{0}ValueChanged, self))\r\n", upName);
                break;
            case EUIControlDataType.Slider:
                sb.AppendFormat("    self:registerCommand(\"on{0}ValueChanged\", Slot(self.on{0}ValueChanged, self))\r\n", upName);
                break;
            default:
                break;
        }
        return sb.ToString();
    }

    public string GetLuaViewModelBindProp() //右键复制 给window文件的绑定
    {
        if (!data.IsHasTarget())
            return "";

        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        var sb = new StringBuilder();

        switch (data.type)
        {
            case EUIControlDataType.Text:
            case EUIControlDataType.TextMeshProUGUI:
                sb.AppendFormat("    self.{0} = UIControls.BindableProp.new()\r\n    table.insert(self.allBinder, self.{0})\r\n    self.{0}:bind(Functor(self._bindPropertyChanged, self, \"{0}\"))\r\n", propName);
                break;
            case EUIControlDataType.Image:
            case EUIControlDataType.RawImage:
                sb.AppendFormat("    self.{0} = UIControls.BindableProp.new()\r\n    table.insert(self.allBinder, self.{0})\r\n    self.{0}:bind(Functor(self._bindPropertyChanged, self, \"{0}\"))\r\n", propName);
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                sb.AppendFormat("    self.{0} = UIControls.BindableProp.new()\r\n    table.insert(self.allBinder, self.{0})\r\n    self.{0}:bind(Functor(self._bindPropertyChanged, self, \"{0}\"))\r\n", propName);
                break;
            case EUIControlDataType.Slider:
                sb.AppendFormat("    self.{0} = UIControls.BindableProp.new()\r\n    table.insert(self.allBinder, self.{0})\r\n    self.{0}:bind(Functor(self._bindPropertyChanged, self, \"{0}\"))\r\n", propName);
                break;
            default:
                break;
        }

        for (int i = 0; i < CtrlItemData.BindAllTypes.Count; ++i)
        {
            var type = CtrlItemData.BindAllTypes[i];
            if (data.GetBindFlag(type))
            {
                var typeName = type.ToString();
                sb.AppendFormat(
                    "    self.{0}{1} = UIControls.BindableProp.new()\r\n    table.insert(self.allBinder, self.{0}{1})\r\n    self.{0}{1}:bind(Functor(self._bindPropertyChanged, self, \"{0}{1}\"))\r\n",
                    propName, typeName);
            }
        }

        return sb.ToString();
    }

    public string GetLuaViewModelBindProp_new() //右键复制 给window文件的绑定
    {
        if (!data.IsHasTarget())
            return "";
        if (data.isNotGeneratorCode)
            return "";

        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        var sb = new StringBuilder();
        if (string.IsNullOrEmpty(data.extraFunc[CtrlItemData.BINDNULLINDEX]))
            switch (data.type)
            {
                case EUIControlDataType.RedDot:
                    if (string.IsNullOrEmpty(data.arg))
                        sb.AppendFormat("    self.{0} = BindableProp()\r\n", propName, data.arg);
                    break;
                case EUIControlDataType.Button:
                    break;
                case EUIControlDataType.OSALScrollView:
                case EUIControlDataType.OSALGridView:
                    sb.AppendFormat("    self.{0} = OSAManager(self, {{}})\r\n", propName);
                    break;
                case EUIControlDataType.OSALScrollViewLazy:
                case EUIControlDataType.OSALGridViewLazy:
                    sb.AppendFormat("    self.{0} = CellManagerLazy(self, {1}Child, Slot(self.get{2}CellData, self))\r\n", propName, data.arg, upName);
                    break;
                default:
                    sb.AppendFormat("    self.{0} = BindableProp()\r\n", propName);
                    break;
            }
        for (int i = 0; i < CtrlItemData.BindAllTypes.Count; ++i)
        {
            if (string.IsNullOrEmpty(data.extraFunc[i]))
            {
                var type = CtrlItemData.BindAllTypes[i];
                if (data.GetBindFlag(type))
                {
                    var typeName = type.ToString();
                    sb.AppendFormat(
                        "    self.{0}{1} = BindableProp()\r\n",
                        propName, typeName);
                }
            }
        }

        return sb.ToString();
    }

    public string GetLuaViewModelPropList()
    {
        if (!data.IsHasTarget())
            return "";

        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        var sb = new StringBuilder();
        if (string.IsNullOrEmpty(data.extraFunc[CtrlItemData.BINDNULLINDEX]))
            switch (data.type)
            {
                case EUIControlDataType.RedDot:
                    if (string.IsNullOrEmpty(data.arg))
                        sb.AppendFormat("    self.{0} = BindableProp()\r\n", propName, data.arg);
                    break;
                case EUIControlDataType.Button:
                    break;
                case EUIControlDataType.OSALScrollView:
                case EUIControlDataType.OSALGridView:
                    sb.AppendFormat("    self.{0} = OSAManager(self, {{}})\r\n", propName);
                    break;
                case EUIControlDataType.OSALScrollViewLazy:
                case EUIControlDataType.OSALGridViewLazy:
                    sb.AppendFormat("    self.{0} = CellManagerLazy(self, {1}Child, Slot(self.get{2}CellData, self))\r\n", propName, data.arg, upName);
                    break;
                default:
                    sb.AppendFormat("    self.{0} = BindableProp()\r\n", propName);
                    break;
            }
        for (int i = 0; i < CtrlItemData.BindAllTypes.Count; ++i)
        {
            if (string.IsNullOrEmpty(data.extraFunc[i]))
            {
                var type = CtrlItemData.BindAllTypes[i];
                if (data.GetBindFlag(type))
                {
                    var typeName = type.ToString();
                    sb.AppendFormat(
                        "    self.{0}{1} = BindableProp()\r\n",
                        propName, typeName);
                }
            }
        }

        return sb.ToString();
    }

    public string GetLuaViewModelFunc(string viewModelName) //右键复制 给window文件的注册
    {
        if (!data.IsHasTarget())
            return "";

        var propName = GetPropName();
        var upName = ToUpperFirst(propName);
        var sb = new StringBuilder();
        switch (data.type)
        {
            case EUIControlDataType.Button:
                sb.AppendFormat("function {1}:on{0}Click()\r\n    \r\nend\r\n", upName, viewModelName);
                break;
            case EUIControlDataType.OSALScrollView:
            case EUIControlDataType.OSALGridView:
                break;
            case EUIControlDataType.OSALScrollViewLazy:
            case EUIControlDataType.OSALGridViewLazy:
                sb.AppendFormat("function {1}:get{0}CellData(index)\r\n    \r\nend\r\n", upName, viewModelName);
                break;
            case EUIControlDataType.InputField:
            case EUIControlDataType.TMP_InputField:
                break;
            case EUIControlDataType.Slider:
                break;
            default:
                break;
        }
        return sb.ToString();
    }

    public string GetLuaBindExtraFuncCode(string viewName)
    {
        if (!data.IsHasTarget())
            return "";

        var propName = GetPropName();
        var sb = new StringBuilder();
        if (!string.IsNullOrEmpty(data.extraFunc[CtrlItemData.BINDNULLINDEX]))
        {
            if (!data.extraGeneratorFunc[CtrlItemData.BINDNULLINDEX])
                sb.AppendFormat("function {1}.{0}DefaultViewFunction({2})\r\n    return {2}\r\nend\r\n", propName, viewName, DecodeArgString(data.extraFunc[CtrlItemData.BINDNULLINDEX], true));
        }

        for (int i = 0; i < CtrlItemData.BindAllTypes.Count; ++i)
        {
            var type = CtrlItemData.BindAllTypes[i];
            if (data.GetBindFlag(type))
            {
                var typeName = type.ToString();
                if (!string.IsNullOrEmpty(data.extraFunc[i]))
                {
                    if (!data.extraGeneratorFunc[i])
                        sb.AppendFormat("function {1}.{0}{2}ViewFunction({3})\r\n    return {3}\r\nend\r\n", propName, viewName, typeName, DecodeArgString(data.extraFunc[i], true));
                }
            }
        }

        return sb.ToString();
    }

    public string GetPropName()
    {
        var propName = data.name;
        if (data.isList)
        {
            propName = string.Format("{0}_{1}", data.listName, data.index);
        }
        return propName;
    }
    #endregion lua
}